package com.lxxin.service.impl;

import com.lxxin.dao.MessageDao;
import com.lxxin.dao.UserDao;
import com.lxxin.pojo.Message;
import com.lxxin.pojo.User;
import com.lxxin.service.MessageService;
import com.lxxin.utils.IpAddressUtils;
import com.lxxin.utils.MD5Utils;
import com.lxxin.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class MessageServiceImpl implements MessageService {
    @Autowired
    private MessageDao messageDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private RedisUtil redisUtil;

    
    @Override
    public List<Message> findMessageList(Integer currentPage, Integer pageSize) {
        List<Message> messageList = messageDao.findMessageList();
        messageList.forEach(x -> x.getUser());
        List<Message> newMessageList = dealMessageList(messageList);
        newMessageList = page(newMessageList, currentPage, pageSize);
        return newMessageList;
    }

    @Override
    public Integer findMessageCount() {
        return messageDao.findMessageCount();
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public int saveMessage(Message message, HttpServletRequest request) {
        message.setCreateTime(System.currentTimeMillis());
//        获取客户端ip地址
        String ipAddress = IpAddressUtils.getIpAddress(request);
//        从请求头中获取token信息
        String token = request.getHeader("token");
        if(!StringUtils.isEmpty(token)){
            User user = (User) redisUtil.get(token);
            if(user != null){
//                token校验通过则为管理员评论
                message.getUser().setId(user.getId());
                message.setAdminMessage(true);
                userDao.saveUser(message.getUser());
                return messageDao.saveMessage(message);
            }
        }
//        普通用户评论，根据ip地址获取用户信息
        User userByIp = userDao.findUserByIp(ipAddress);
//        判断用户是否存在
        if(userByIp != null){
            message.getUser().setId(userByIp.getId());
            message.getUser().setNickname(message.getUser().getNickname());
            message.getUser().setEmail(message.getUser().getEmail());
            message.getUser().setAvatar(getAvatarUrl(message.getUser().getEmail()));
            message.getUser().setUpdateTime(System.currentTimeMillis());
            userDao.updateUser(message.getUser());
        }
        else{
            message.getUser().setAvatar(getAvatarUrl(message.getUser().getEmail()));
            message.getUser().setIp(ipAddress);
            message.getUser().setType(0);
            message.getUser().setCreateTime(System.currentTimeMillis());
            message.getUser().setUpdateTime(System.currentTimeMillis());
        }
        userDao.saveUser(message.getUser());
        return messageDao.saveMessage(message);
    }

    /**
     * 找到所有没有父评论的留言
     *
     * @param messageList
     * @return
     */
    public List<Message> dealMessageList(List<Message> messageList) {
        List<Message> newMessageList = new ArrayList<>();
        for (Message message : messageList) {
            if (message.getParentMsgId() == null) {
                newMessageList.add(message);
                List<Message> childList = getChildMessage(message, messageList);
                message.setChildMessages(childList);
                message.setChildMessagesCount(childList.size());
            }
        }
        return newMessageList;
    }

    /**
     * 对顶级留言进行处理，广度优先搜索，逐个加入链表，最后按时间降序排序后返回
     *
     * @param message
     * @param messageList
     * @return
     */
    public List<Message> getChildMessage(Message message, List<Message> messageList) {
        ArrayDeque<Message> queue = new ArrayDeque<>();
        List<Message> childList = new ArrayList<>();
        queue.addLast(message);
        while (!queue.isEmpty()) {
            Message tmpParent = queue.removeFirst();
            for (Message c : messageList) {
                if (c.getParentMsgId() != null && c.getParentMsgId().equals(tmpParent.getId())) {
                    Message tmp = new Message();
                    tmp.setId(tmpParent.getId());
                    tmp.setUser(tmpParent.getUser());
                    c.setParentMessage(tmp);
                    childList.add(c);
                    queue.addLast(c);
                }
            }
        }
        Collections.sort(childList, (a, b) -> (int) (b.getCreateTime() - a.getCreateTime()));
        return childList;
    }

    /**
     * 对处理后的留言进行手动分页
     * @param messageList
     * @param currentPage
     * @param pageSize
     * @return
     */
    public List<Message> page(List<Message> messageList, int currentPage, int pageSize) {
        List<Message> currentPageList = new ArrayList<>();
        if(messageList != null && messageList.size() > 0) {
            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
            for (int i = 0; i < pageSize && i < messageList.size() - currIdx; i++) {
                Message data = messageList.get(currIdx + i);
                currentPageList.add(data);
            }
        }
        return currentPageList;
    }

    /**
     * 根据邮箱获取头像
     * @param email
     * @return
     */
    public String getAvatarUrl(String email) {
        //如果是QQ邮箱
        if(email.indexOf("@qq.com") >= 0) {
            String prefix = email.replace("@qq.com", "");
            if(prefix.matches("[1-9][0-9]{4,}")) {
                return "https://q2.qlogo.cn/headimg_dl?dst_uin="+ prefix +"&spec=100";
            }
        }
        //Gravatar头像
        String md5Email = MD5Utils.code(email);
        return "http://cdn.v2ex.com/gravatar/"+ md5Email +"?s=100";
    }
}
